package com.acwing.partition13;

import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author `RKC`
 * @date 2022/3/10 21:40
 */
public class AC1206剪格子 {

    private static final int N = 11;
    private static final int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    private static int[][] w = new int[N][N];
    private static boolean[][] st = new boolean[N][N];
    private static int[] parent = new int[N * N];

    private static Set<String> stateSet = new HashSet<>();
    private static Set<Integer> connectSet = new HashSet<>(N * N);

    private static int n, m, sum = 0, ans = 100;

    private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        String[] ss = reader.readLine().split(" ");
        n = Integer.parseInt(ss[1]);
        m = Integer.parseInt(ss[0]);
        for (int i = 0; i < n; i++) {
            ss = reader.readLine().split(" ");
            for (int j = 0; j < m; j++) {
                w[i][j] = Integer.parseInt(ss[j]);
                sum += w[i][j];
            }
        }
        if ((sum & 1) == 1) ans = 0;
        else {
            st[0][0] = true;
            //TODO 通过数据9/11
            dfs(w[0][0], 1);
        }
        if (ans == 100) ans = 0;
        writer.write(ans + "\n");
        writer.flush();
    }

    private static void dfs(int s, int k) {
        if (s > sum / 2 || k >= ans) return;
        String state = getState();
        if (stateSet.contains(state)) return;
        stateSet.add(state);
        if (s == sum / 2) {
            //检查目前是否是两个连通块
            if (checkConnect()) ans = Math.min(ans, k);
            return;
        }
        //剪枝，找最大的进行遍历
        List<int[]> pairs = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (!st[i][j]) {
                    pairs.add(new int[]{i, j, w[i][j]});
                }
            }
        }
        pairs.sort((o1, o2) -> Integer.compare(o2[2], o1[2]));
        for (int[] pair : pairs) {
            int x = pair[0], y = pair[1];
            st[x][y] = true;
            dfs(s + pair[2], k + 1);
            st[x][y] = false;
        }
    }

    private static boolean checkConnect() {
        for (int i = 0; i < parent.length; i++) parent[i] = i;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (int[] dir : dirs) {
                    int nx = i + dir[0], ny = j + dir[1];
                    if (nx < 0 || nx >= n || ny < 0 || ny >= m || st[nx][ny] != st[i][j]) continue;
                    int a = find(i * m + j), b = find(nx * m + ny);
                    if (a != b) {
                        parent[a] = b;
                    }
                }
            }
        }
        connectSet.clear();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                connectSet.add(find(i * m + j));
            }
        }
        return connectSet.size() == 2;
    }

    private static String getState() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (st[i][j]) sb.append("1");
                else sb.append("0");
            }
        }
        return sb.toString();
    }

    private static int find(int x) {
        if (parent[x] != x) parent[x] = find(parent[x]);
        return parent[x];
    }
}
